from typing import List
from common.enum.strategy_group_enum import StrategyGroup
from common.enum.strategy_type_enum import StrategyType
from dto.strategy_info import StrategyInfoMetadata
from dto.strategy_assessment import RiskAssessment
from dto.strategy_stock_day import StrategyStockDay
from service.strategy.base_strategy import BaseStrategy


class ThirtyDaysPriceVolumeStrategy(BaseStrategy):
    """
    30天内价格与成交量比较策略。
    """

    def analyze(self, trade_info_list: List[StrategyStockDay]) -> RiskAssessment:
        """
        分析30天内价格是否重复出现，以及当前成交量是否远小于之前相同价格的成交量。
        """
        node_point = 0
        description = ""

        # 确保有至少30天的交易数据
        if len(trade_info_list) < 30:
            raise ValueError("数据不足，要求至少30天的交易数据。")

        # 用于记录价格与对应成交量的字典
        price_volume_map = {}

        for day in trade_info_list:
            price = day.close  # 假设 close_price 是日收盘价
            volume = day.vol

            if price in price_volume_map:
                previous_volume = price_volume_map[price]
                if volume < previous_volume:
                    node_point += 5  # 成交量小于之前的相同价位成交量，基础得分5
                    reduction_percentage = ((previous_volume - volume) / previous_volume) * 100

                    # 每小10%，额外加2分
                    additional_points = int(reduction_percentage // 10) * 2
                    node_point += additional_points

                    description += (
                        f"当前价格 {price} 在过去30天内重复出现，"
                        f"当前成交量 ({volume}) 小于之前成交量 ({previous_volume})，"
                        f"减少了 {reduction_percentage:.2f}%，额外得 {additional_points} 分。\n"
                    )

            # 更新字典中的价格与成交量映射
            price_volume_map[price] = volume

        return RiskAssessment(
            stock_code=trade_info_list[0].stock_code,
            description=description,
            config=self.strategyConfig(),
            node_point=node_point,
        )

    def strategyConfig(self) -> StrategyInfoMetadata:
        """
        返回策略的配置
        """
        return StrategyInfoMetadata(
            strategy_code="thirty_days_price_volume",
            strategy_name="30天价格成交量对比",
            strategy_group=StrategyGroup.RISK,
            strategy_type=StrategyType.PRICE,
            analysis_day=30,
            strategy_level=3,
        )
